<?

/**
 * GCalendar class
 *
 * Esta clase maneja la comunicacion con el Google Calendar
 * @author Alejandro Garcia del Rio <alejandro.garciadelrio@elserver.com>
 * @version 1.0
 * @package GCalendar
*/
class GCalendar extends Core {

	static protected $instancia;
	static protected $opciones = array();
	private $_client = null;
	private $id_usuario = null;

	/**
	 * Constructor de la clase.
	 * 
	 * @param array $opciones (opcional) Opciones validas para esta clase
	 */
	function __construct ($id_usuario=null, $opciones=null) {
		// Llamo al constructor del parent tambien
		parent::__construct();
		// Guardo las opciones si me definio alguna
		if ($opciones)
			$this->opciones($opciones);

		// Cargo las librerias del Zend de Google Calendar
		Zend_Loader::loadClass('Zend_Gdata');
		Zend_Loader::loadClass('Zend_Gdata_AuthSub');
		Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
		Zend_Loader::loadClass('Zend_Gdata_Calendar');

		// Obtengo un objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Defino el id_usuario (por parametro o por sesion)
		$id_usuario = ($id_usuario)? $id_usuario : $Session->get('usuario.id');

//		$user = preg_replace('/@.*/', '', $db->get_var("SELECT sso FROM usuarios WHERE id_usuario = '".addslashes($id_usuario)."'")).'.elserver';
//		$pass = md5($user);

		$user = CONFIG_GOOGLE_USER;
		$pass = CONFIG_GOOGLE_PASS;

		// Lo logueo automaticamente
		if ( !$this->login($user, $pass) )
			return false;

		return true;
	}

	/**
	 * Setea las opciones 
	 * 
	 * @param array $opciones (opcional) Opciones validas para esta clase. Si esta vacio, funciona como un getter.
	 * @return array $opciones Listado de opciones
	 */
	public function opciones ($opciones=null) {
		return self::$opciones = parent::opciones(self::$opciones, $opciones);
	}

	/**
	 * Devuelve una unica instancia de esta clase
	 * 
	 * @return object Instancia de esta clase
	 */
	public static function getInstance() {
		if (!self::$instancia instanceof self)
			self::$instancia = new self;
		return self::$instancia;
	}

	/**
	 * Se loguea a los servicios de google
	 * 
	 * @return string
	 */
	public function login ($user, $pass) {
		// Creo el cliente
		return $this->_client = Zend_Gdata_ClientLogin::getHttpClient($user,$pass,Zend_Gdata_Calendar::AUTH_SERVICE_NAME);
	}

	/**
	 * Agrega una tarea al google calendar
	 * 
	 * @param array $tarea La informacion de la tarea a agregar
	 * @return string
	 */
	public function agregar ($tarea) {

		// Obtengo el calendario de pendientes de este usuario
		$calendar = $this->Calendar();

		// Valido que exista el cliente conectado
		if (!$this->_client)
			return $this->fail('No estas conectado a gcalendar');

		// Creo el objeto de nueva tarea de GCalendar
		$gdataCal = new Zend_Gdata_Calendar($this->_client);
		$newEvent = $gdataCal->newEventEntry();

		// Defino el titulo y el contenido
		$newEvent->title = $gdataCal->newTitle($tarea['titulo']);
		$newEvent->content = (isset($tarea['descripcion']) && !empty($tarea['descripcion']))? $gdataCal->newContent($tarea['descripcion']) : '';

		// Defino el comienzo y el fin
		$when = $gdataCal->newWhen();
		$when->startTime = date("Y-m-d\TH:i:s.000-03:00", strtotime($tarea['fecha_inicio']));
		$when->endTime = date("Y-m-d\TH:i:s.000-03:00", strtotime($tarea['fecha_fin']));
		$newEvent->when = array($when);

		// Creo el evento!
		$url = preg_replace('/\/default/', '/'.end(explode('/', $calendar)), Zend_Gdata_Calendar::CALENDAR_EVENT_FEED_URI);
		$createdEvent = $gdataCal->insertEvent($newEvent, $url);
//		$createdEvent = $gdataCal->insertEvent($newEvent, 'http://www.google.com/calendar/feeds/3snmuilsr510oa3olcmuu0n45c%40group.calendar.google.com/private/full');

		return $createdEvent->id->text;
	}

	/**
	 * Agrega una tarea al google calendar
	 * 
	 * @param array $tarea La informacion de la tarea a agregar
	 * @return string
	 */
	public function eliminar ($id_gcalendar) {

		// Valido que exista el cliente conectado
		if (!$this->_client)
			return $this->fail('No estas conectado a gcalendar');

		// Obtengo el evento
		$gdataCal = new Zend_Gdata_Calendar($this->_client);
		$event = $gdataCal->getCalendarEventEntry($id_gcalendar);

		// Elimino el evento!
		$event->delete();

		return true;
	}

	/**
	 * Modifica un evento en GCalendar
	 * 
	 * @param string $id_gcalendar El id de gcalendar para este evento
	 * @param array $tarea La informacion de la tarea a agregar
	 * @return string
	 */
	public function modificar ($id_gcalendar, $tarea) {

		// Valido que exista el cliente conectado
		if (!$this->_client)
			return $this->fail('No estas conectado a gcalendar');

		// Obtengo el evento
		$gdataCal = new Zend_Gdata_Calendar($this->_client);

		// Obtengo la tarea de GCalendar
		if (!($tareaOld = $gdataCal->getCalendarEventEntry($id_gcalendar)))
			return $this->fail('No existe el evento en Google Calendar');

		// Modifico el titulo
		if ($tarea['titulo'])
			$tareaOld->title = $gdataCal->newTitle($tarea['titulo']);

		// Modifico la descripcion
		if ($tarea['descripcion'])
			$tareaOld->content = $gdataCal->newContent($tarea['descripcion']);

		// Creo un objeto when
		$when = $gdataCal->newWhen();

		// Modifico la fecha de inicio
		$when->startTime = ($tarea['fecha_inicio'])? date("Y-m-d\TH:i:s.000-03:00", strtotime($tarea['fecha_inicio'])) : $tareaOld->when[0]->startTime;

		// Modifico la fecha de finalizacion
		$when->endTime = ($tarea['fecha_fin'])? date("Y-m-d\TH:i:s.000-03:00", strtotime($tarea['fecha_fin'])) : $tareaOld->when[0]->endTime;

		// Guardo el objeto when actualizado en la tarea
		$tareaOld->when = array($when);

		// Ejecuto la actualizacion
		$tareaOld->save();

		return true;
	}

	/**
	 * Marca una tarea como realizada en GCalendar
	 * 
	 * @param string $id_gcalendar El id de gcalendar para este evento
	 * @return string
	 */
	public function hecho ($id_gcalendar) {

		// Obtengo el calendario "hecho" de este usuario
		$hechoCalendar = $this->hechoCalendar();

		// Valido que exista el cliente conectado
		if (!$this->_client)
			return $this->fail('No estas conectado a gcalendar');

		// Obtengo el evento
		$gdataCal = new Zend_Gdata_Calendar($this->_client);

		// Obtengo la tarea de GCalendar
		if (!($oldEvent = $gdataCal->getCalendarEventEntry($id_gcalendar)))
			return $this->fail('No existe el evento en Google Calendar');

		// Creo un nuevo evento
		$newEvent = $gdataCal->newEventEntry();

		// Copio la informacion del contenido anterior
		$newEvent->title = $oldEvent->title;
		$newEvent->content = $oldEvent->content;

		// Defino el comienzo y el fin
		$newEvent->when = $oldEvent->when;

		// Creo la tarea en el calendario "Hecho"
		$url = preg_replace('/\/default\//', '/'.end(explode('/', $hechoCalendar)).'/', Zend_Gdata_Calendar::CALENDAR_EVENT_FEED_URI);
		$createdEvent = $gdataCal->insertEvent($newEvent, $url);

		// Elimino la tarea actual del calendario por defecto
		$oldEvent->delete();

		// Devuelvo el nuevo codigo de tarea
		return $createdEvent->id->text;
	}

	/**
	 * Devuelve la url del calendario de tareas "hechas"
	 * 
	 * @param integer $id_usuario (Opcional) El id de usuario del que se quiere el calendario de hecho
	 * @return string
	 */
	public function hechoCalendar ($id_usuario=null) {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo el objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Defino el id_usuario (por parametro o por sesion)
		$id_usuario = ($id_usuario)? $id_usuario : $Session->get('usuario.id');

		// No estas logueado
		if (!$id_usuario)
			return ($this)? $this->fail('No estas logueado') : false;

		// Saneamiento de variables
		$id_usuario = addslashes($id_usuario);

		// Buso el calendario en la tabla del usuario para ver si ya esta creado
		if ( ($hechoCalendar = $db->get_var("SELECT gcalendar_hecho FROM usuarios WHERE id_usuario = '$id_usuario'")) && ($hechoCalendar != '') )
			return $hechoCalendar;

		// Obtengo el sso del usuario
		$usuario = SSO::usuario($id_usuario);
		$sso = $usuario['sso'];

		// No existia, lo creo y guardo en la base
		$hechoCalendar =  $this->agregar_calendario("$sso - Hecho", "Calendario de las tareas realizadas para $sso");
		$db->update('usuarios', array('id_usuario' => $id_usuario, 'gcalendar_hecho' => $hechoCalendar));

		return $hechoCalendar;
	}

	/**
	 * Devuelve la url del calendario de tareas pendientes
	 * 
	 * @param integer $id_usuario (Opcional) El id de usuario del que se quiere el calendario de hecho
	 * @return string
	 */
	public function Calendar ($id_usuario=null) {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo el objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Defino el id_usuario (por parametro o por sesion)
		$id_usuario = ($id_usuario)? $id_usuario : $Session->get('usuario.id');

		// No estas logueado
		if (!$id_usuario)
			return ($this)? $this->fail('No estas logueado') : false;

		// Saneamiento de variables
		$id_usuario = addslashes($id_usuario);

		// Buso el calendario en la tabla del usuario para ver si ya esta creado
		if ( ($Calendar = $db->get_var("SELECT gcalendar FROM usuarios WHERE id_usuario = '$id_usuario'")) && ($Calendar != '') )
			return $Calendar;

		// Obtengo el sso del usuario
		$usuario = SSO::usuario($id_usuario);
		$sso = $usuario['sso'];

		// No existia, lo creo y guardo en la base
		$options = array('color' => '5229A3', 'hidden' => 'false');
		$Calendar =  $this->agregar_calendario("$sso - Pendiente", "Calendario de las tareas pendientes para $sso", $options);
		$db->update('usuarios', array('id_usuario' => $id_usuario, 'gcalendar' => $Calendar));

		return $Calendar;
	}

	/**
	 * Agrega un nuevo calendario al Google Calendar de este usuario
	 * 
	 * @param string $nombre Nombre del calendario a crear
	 * @param string $descripcion (Opcional) Descripcion del calendario a crear
	 * @return string
	 */
	public function agregar_calendario ($nombre, $descripcion, $opciones=array()) {

		// Valido que exista el cliente conectado
		if (!$this->_client)
			return $this->fail('No estas conectado a gcalendar');

		// Defino el color
		$color = ($opciones['color'])? $opciones['color'] : '333333';
		// Defino el access type (hidden/public)
		$hidden = (string)($opciones['hidden'])? $opciones['hidden'] : 'true';

		// Defino el xml request
		$request = "
			<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005' xmlns:gCal='http://schemas.google.com/gCal/2005'>
				<title type='text'><![CDATA[".$nombre."]]></title>
				<summary type='text'><![CDATA[".$descripcion."]]></summary>
				<gCal:timezone value='America/Buenos_Aires'></gCal:timezone>
				<gCal:hidden value='$hidden'></gCal:hidden>
				<gCal:selected value='true'/>
				<gCal:accesslevel value='owner'/>
				<gCal:color value='#$color'></gCal:color>
				<gd:where rel='' label='' valueString=''></gd:where>
			</entry>";

		// Creo el objeto de nueva tarea de GCalendar
		$gdataCal = new Zend_Gdata_Calendar($this->_client);

		// Creo el calendario!
		$createdCalendar = $gdataCal->insertCalendar($request, 'https://www.google.com/calendar/feeds/default/owncalendars/full');

		return $createdCalendar;
	}

	/**
	 * Devuelve la url del google calendar para incluirlo
	 * 
	 * @return string
	 */
	public function calendar_url () {

		// Obtengo el codigo del calendario de eventos hechos
		$gcalendar = end(explode('/', $this->Calendar()));

		// Obtengo un objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Obtengo el usuario
		$user = preg_replace('/(\@.*$)/', '.elserver', $Session->get('usuario.sso'));

		$url = "http://www.google.com/calendar/embed?mode=WEEK&height=1300&wkst=2&bgcolor=%23dddddd&amp;src=$gcalendar&amp;color=%235229A3&amp;ctz=America%2FArgentina%2FBuenos_Aires";

		return $url;
	}

}

?>
